const Category = require('../../../models/blog_category');
const Article = require('../../../models/blog_article');
const Tag = require('../../../models/blog_tags');
const User = require('../../../models/admin_users');
const ArticleCategory = require('../../../models/article_category_tags');
const Comment = require('../../../models/blog_comment');
const authCodeFunc = require('../../../utils/authCode');
const Utils = require('../../../utils');
const knex = require('../../../models/knex');

/**
 * 文章管理控制器
 */
const ControllerArticle = {
    getTabs: async function (req, res, next) {
        try {
            const articles = await Article.all();
            let list = Utils.getTabs(articles); //* tabs列表

            res.json({ code: 200, data: { list } })
        } catch (e) {
            res.json({ code: 0, data: e })
        }
    },
    /* 获取列表 */
    getList: async function (req, res, next) {
        try {
            let { status, per_page, page, keywor } = req.query;
            let params = {};
            let newParam = {};
            let articles = Article.table;
            let or = ArticleCategory.table;
            let users = User.table;
            let ac = '';
            let offset = (per_page * (page - 1)) || 0; //计算当前页

            keywor = decodeURI(keywor); //* 对前端传递过来的信息进行解码

            if (keywor) params.title = keywor;
            if (status != 0) {
                ac = `${articles}.status = ${status}`;
                newParam.status = status
            }

            const total = (await Article.select(newParam)).length; // 总数据
            // 文章联表查询
            const list = await knex(articles)
                .join(users, `${articles}.issuer_id`, `${users}.id`)
                .join(or, `${articles}.id`, `${or}.article_id`)
                .whereRaw(ac).orWhere(params) // 条件查询
                .limit(Number(per_page)).offset(Number(offset)) // 分页查询
                .orderBy(`${articles}.sort`) // 排序
                .select(
                    `${articles}.id`,
                    `${articles}.title`,
                    `${articles}.summary`,
                    `${articles}.status`,
                    `${articles}.support`,
                    `${articles}.click`,
                    `${articles}.image_url`,
                    `${articles}.content`,
                    `${articles}.sort`,
                    `${articles}.created_time`,
                    `${users}.user_name as issuer_name`,
                    `${or}.category_id`,
                    `${or}.tag_ids`,
                )

            let number = Math.ceil(total / per_page); // 计算出信息总页数

            res.json({ code: 200, data: { list, total, number } })
        } catch (e) {
            res.json({ code: 0, data: e })
        }
    },
    /* 获取详情 */
    getById: async function (req, res, next) {
        try {
            let { id } = req.query;
            let articles = Article.table;
            let or = ArticleCategory.table;

            // 文章详情联表查询
            const list = await knex(articles)
                .join(or, `${articles}.id`, `${or}.article_id`)
                .select(
                    `${articles}.id`,
                    `${articles}.title`,
                    `${articles}.summary`,
                    `${articles}.status`,
                    `${articles}.support`,
                    `${articles}.click`,
                    `${articles}.image_url`,
                    `${articles}.content`,
                    `${articles}.sort`,
                    `${articles}.created_time`,
                    `${or}.category_id`,
                    `${or}.tag_ids`,
                )
                .whereRaw(`${articles}.id = ${id}`) // 条件查询

            res.json({ code: 200, data: { list: list[0] } })
        } catch (e) {
            res.json({ code: 0, data: e })
        }
    },
    /* 创建 */
    Insert: async function (req, res, next) {
        try {
            let authorization = req.headers.authorization;
            let tokens = authorization.split(' ');
            let user_decode = authCodeFunc(tokens[1], 'DECODE');
            let user_info = user_decode.str.split('\t');
            let issuer_id = user_info[0];
            let { title, summary, status, support, image_url, content, category_id, tag_ids } = req.body;
            let params = {
                title, summary, status, support, content,
                issuer_id, created_time: new Date().getTime()
            };

            if (!title || !category_id || !summary || !content) return res.json({ code: 0, msg: '参数错误' })

            if (image_url) params.image_url = image_url;
            // if (tag_ids) params.tag_ids = tag_ids;

            const article_id = (await Article.insert(params))[0];

            await ArticleCategory.insert({ article_id, category_id, tag_ids: tag_ids.join() })

            res.json({ code: 200, msg: status == 1 ? '创建成功' : '已存放草稿' })
        } catch (e) {
            res.json({ code: 0, data: e })
        }
    },
    /* 编辑 */
    update: async function (req, res, next) {
        try {
            let authorization = req.headers.authorization;
            let tokens = authorization.split(' ');
            let user_decode = authCodeFunc(tokens[1], 'DECODE');
            let user_info = user_decode.str.split('\t');
            let modifier_id = user_info[0];
            let { id, title, summary, status, support, image_url, content, category_id, tag_ids } = req.body;
            let params = {
                title, summary, status, support, content,
                modifier_id, update_time: new Date().getTime()
            };

            const article_id = (await ArticleCategory.select({ article_id: id }))[0].id;

            if (!title || !category_id || !summary || !content) return res.json({ code: 0, msg: '参数错误' })

            if (image_url) params.image_url = image_url;
            // if (tag_ids) params.tag_ids = tag_ids;

            await Article.update(id, params);
            await ArticleCategory.update(article_id, { category_id, tag_ids: tag_ids.join() })

            res.json({ code: 200, msg: '编辑成功' })
        } catch (e) {
            res.json({ code: 0, data: e })
        }
    },
    /* 删除 */
    del: async function (req, res, next) {
        try {
            let { id } = req.body;
            let ids = typeof (id) === 'number' ? [id] : id.split(',');
            let or = ArticleCategory.table;
            let comments = Comment.table;

            await Article.batchDel(ids);
            await knex(or).whereIn('article_id', ids).del();
            await knex(comments).whereIn('article_id', ids).del();

            res.json({ code: 200, msg: '删除成功' })
        } catch (e) {
            res.json({ code: 0, data: e })
        }
    },

    /* 文章分类列表 */
    getCategoryList: async function (req, res, next) {
        try {

            const list = await Category.all();
            let category_id = list.map(v => v.id);
            const tags = await Tag.batchKeySelect('category_id', category_id)


            list.forEach((i) => {
                i.disabled = true;

                tags.forEach((v) => {
                    if (i.id == v.category_id) {
                        i.disabled = false
                    }
                })

            })

            res.json({ code: 200, data: { list } })
        } catch (e) {
            res.json({ code: 0, data: e })
        }
    },

    /* 标签列表 */
    getTagList: async function (req, res, next) {
        try {
            let { category_id } = req.query;

            const tags = await Tag.select({ category_id });

            res.json({ code: 200, data: { tags } })
        } catch (e) {
            res.json({ code: 0, data: e })
        }
    },

    /* 博文排序 */
    onUpdateSort: async function (req, res, next) {
        try {
            let sortList = JSON.parse(req.body.sortList);

            sortList.forEach(async data => {
                let id = data.id;

                await Article.update(id, { sort: data.sort })
            })

            res.json({ code: 200, msg: "排序成功" })
        } catch (e) {
            res.json({ code: 0, data: e })
        }
    },

    /* 博文发布、草稿、回收状态切换*/
    articleStateChange: async function (req, res, next) {
        try {
            let { id, status } = req.body;
            let text = '';

            switch (status) {
                case 1:
                    text = '发布'
                    break;

                case 2:
                    text = '保存草稿'
                    break;

                default:
                    text = '存放回收箱'
                    break;
            }

            // 单一操作
            if (typeof (id) === 'number') {
                const item = await Article.select({ id });
                let same = item[0].status == status;

                if (same) return res.json({ code: 0, msg: `该文章已${text}` });

                await Article.update(id, { status })
            }

            // 批量操作
            if (typeof (id) === 'string') {
                let ids = id.split(',');
                const list = await Article.batchSelect(ids);
                let statusList = list.map(item => item.status);
                let same = statusList.some(item => item == status); // 检索是否存在与当前操作状态相同状态的文章
                let notSame = null;

                if (same) return res.json({ code: 0, msg: `已${text}文章不要重复${text}` });

                switch (status) {
                    case 1:
                        notSame = statusList.some(item => item == 3)

                        if (notSame) return res.json({ code: 0, msg: '在回收箱的不能直接发布' })

                        break;
                    case 3:
                        notSame = statusList.some(item => item == 1)

                        if (notSame) return res.json({ code: 0, msg: '已发布的不能直接回收' });
                        break;
                }

                await Article.batchUpdate(ids, { status });
            }

            res.json({ code: 200, msg: `成功${text}` })
        } catch (e) {
            res.json({ code: 0, data: e })
        }
    },
}

module.exports = ControllerArticle;